﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WcfMail;
using PWMIS.DataMap.Entity;
using WcfMail.Interface;
using WcfMail.Common;
using System.Reflection;
using IBMP.IOC;
using System.Data;
using System.Collections;

namespace WcfMail.Common
{
    /// <summary>
    /// 实体类与系统消息类转换程序
    /// </summary>
    public  class EntityMessage
    {
        private static IConvert _convert = null;

        private static IConvert GetConverter()
        {
            if(_convert==null)
                _convert = Converter.CreateInstance(SerializerType.PdfNet);
            return _convert;
        }

        /// <summary>
        /// 将实体类转换成消息，注：消息不带类型信息和标题信息
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static SystemMessage ConvertToMessage(EntityBase entity)
        {
            IConvert convert = GetConverter();
            SystemMessage msg = new SystemMessage();
            msg.MsgContent = convert.ConvertToString(entity);
            //msg.MsgType = entity.GetType().FullName; 由于是批量，没有必要
            return msg;
        }

        /// <summary>
        /// 将列表中的所有元素转换成消息，每个元素必须是同一个实体类类型
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static List<SystemMessage> ConvertToMessages(IList list)
        {
            List<SystemMessage> result = new List<SystemMessage>();
            IConvert convert = GetConverter();
            if (list.Count > 0)
            {
                string typeName = list[0].GetType().FullName;
                foreach (EntityBase item in list)
                {
                    SystemMessage msg = new SystemMessage();
                    msg.MsgContent = convert.ConvertToString(item);
                    msg.MsgType = typeName;

                    result.Add(msg);
                }
            }
            return result;
        }
        /// <summary>
        /// 将实体类基类的列表转换成系统消息列表，并指定实体类基类列表每个成员的实际类型
        /// </summary>
        /// <param name="list">实体类基类的列表</param>
        /// <param name="factualType">实体类基类列表每个成员的实际类型</param>
        /// <returns>系统消息列表</returns>
        public static List<SystemMessage> ConvertToMessages(IEnumerable<EntityBase> list, Type factualType)
        {
            List<SystemMessage> result = new List<SystemMessage>();
            IConvert convert = GetConverter(); 

            foreach (EntityBase item in list)
            {
                //创建当前 EntityBase 实际类型的实例
                EntityBase factualEntity = (EntityBase)Activator.CreateInstance(factualType);//
                factualEntity.SetPropertyValues(item.PropertyValues);

                SystemMessage msg = new SystemMessage();
                msg.MsgContent = convert.ConvertToString(factualEntity);
                msg.MsgType = factualType.FullName;

                result.Add(msg);
            }
            return result;
        }

        /// <summary>
        /// 将实体类列表转换成系统消息列表，并指定实体类基类列表每个成员的实际类型
        /// </summary>
        /// <typeparam name="Entity">具体的实体类类型</typeparam>
        /// <param name="list">将实体类列表</param>
        /// <returns></returns>
        public static List<SystemMessage> ConvertToMessages<Entity>(List<Entity> list) where Entity : PWMIS.Common.IEntity 
        {
            List<SystemMessage> result = new List<SystemMessage>();
            IConvert convert = GetConverter();
            if (list.Count > 0)
            {
                string typeName = list[0].GetType().FullName;
                foreach (Entity item in list)
                {
                    SystemMessage msg = new SystemMessage();
                    msg.MsgContent = convert.ConvertToString(item);
                    msg.MsgType = typeName;

                    result.Add(msg);
                }
            }
            
            return result;
        }

        /// <summary>
        /// 将系统消息列表转换成指定的实体类对象列表
        /// </summary>
        /// <typeparam name="Entity">具体的实体类类型</typeparam>
        /// <param name="list">系统消息列表</param>
        /// <param name="modelAssemblyName">实体类所在的程序集名称</param>
        /// <returns>实体类列表</returns>
        public static  List<Entity> ConvertToEntitys<Entity>(List<SystemMessage> list, string modelAssemblyName) where Entity : PWMIS.Common.IEntity  
        {
            List<Entity> result = new List<Entity>();
            IConvert convert = GetConverter();
            if (list.Count > 0)
            {
                Type factualType = Unity.Instance.GetCacheType(list[0].MsgType, modelAssemblyName);
                foreach (SystemMessage item in list)
                {
                    if (!string.IsNullOrEmpty(item.MsgContent))
                    {
                        Entity entity = (Entity)convert.ConvertToObject(item.MsgContent, factualType);
                        result.Add(entity);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 将实体类转换成数据表
        /// </summary>
        /// <typeparam name="Entity">实体类类型</typeparam>
        /// <param name="entitys">实际的实体类</param>
        /// <returns>数据表</returns>
        public static DataTable EntitysToDataTable<Entity>(List<Entity> entitys) where Entity : EntityBase  
        {
            if (entitys == null )
                throw new ArgumentException("参数错误，不能为空!");
            if (entitys.Count == 0)
                return null;

            //Entity e = entitys.Count > 0 ? entitys[0] : new Entity();
            Entity e = entitys[0];
            string tableName = e.TableName == null ? "Table1" : e.TableName;
            DataTable dt = new DataTable(tableName);
            foreach (string str in e.PropertyNames)
            {
                DataColumn col = new DataColumn(str);
                object V = e.PropertyList(str);
                col.DataType = V == null || V == DBNull.Value ? typeof(string) : V.GetType();
                dt.Columns.Add(col);
            }
            
            foreach (Entity item in entitys)
            {
                dt.Rows.Add(item.PropertyValues);
            }
            return dt;
        }

        /// <summary>
        /// 将系统消息转换成数据表
        /// </summary>
        /// <param name="list">系统消息列表，注意每个元素的消息类型必须一致</param>
        /// <param name="modelAssemblyName">消息中每个元素的实体类所在的程序集名称</param>
        /// <returns>数据表</returns>
        public static DataTable ConvertToDataTable(List<SystemMessage> list, string modelAssemblyName)
        {
            List<EntityBase> entitys = ConvertToEntitys<EntityBase>(list, modelAssemblyName);
            return entitys.Count ==0?null:EntitysToDataTable(entitys);
        }
    }
}
